package xworker.dataObject.app.model.tree.implnew;

import org.xmeta.ActionContext;
import org.xmeta.Thing;
import org.xmeta.util.ActionContainer;
import xworker.dataObject.data.tree.TreeModel;
import xworker.dataObject.data.tree.TreeModelItem;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class ObjectTreeModel {
    public static TreeModelItem getRoot(ActionContext actionContext){
        Thing self = actionContext.getObject("self");

        TreeModel treeModel = actionContext.getObject("treeModel");

        Object object = self.doAction("getObject", actionContext);
        TreeModelItem rootItem = new TreeModelItem(treeModel, null);
        rootItem.setText(String.valueOf(object) + ": " + (object != null ? object.getClass().getSimpleName() : "unknown"));
        rootItem.setIcon("icons/brick.png");
        rootItem.setSource(object);
        return rootItem;
    }

    public static TreeModelItem createTreModelItem(TreeModelItem parentItem, String name, String type, Object object){
        TreeModelItem item = new TreeModelItem(parentItem.getTreeModel(), parentItem);

        if(type == null){
            type = object != null ? object.getClass().getName() : "unknown";
        }
        item.setText(name + ": " + object );
        //item.setIcon("icons/brick.png");
        item.setSource(object);

        return item;
    }

    public static Object getChilds(ActionContext actionContext) throws Exception{
        //Thing self = actionContext.getObject("self");

        //TreeModel treeModel = actionContext.getObject("treeModel");
        TreeModelItem parentItem = actionContext.getObject("parentItem");

        List<TreeModelItem> items = new ArrayList<>();
        Object value = parentItem.getSource();
        try{
            if(value == null || value.getClass() == null){
                return Collections.emptyList();
            }

            Field[] fields = value.getClass().getFields();
            for(Field field : fields){
                items.add(createTreModelItem(parentItem, field.getName(), field.getType().getName(), field.get(value)));
            }

            Method[] methods = value.getClass().getMethods();
            for(Method method : methods){
                String methodName = method.getName();
                if(methodName.startsWith("get") && method.getParameterTypes().length == 0){
                    try{
                        String name = methodName.substring(3,4).toLowerCase() + methodName.substring(4);

                        items.add(createTreModelItem(parentItem, name, method.getReturnType().getName(), method.invoke(value)));
                    }catch(Throwable e){
                        //log.info("get mehtod error " + method.name);
                    }
                }
            }

            if(value instanceof ActionContext){
                ActionContext ac = (ActionContext) value;
                for(String key : ac.keySet()){
                    items.add(createTreModelItem(parentItem, key, "org.xmeta.ActionContext", ac.get(key)));
                }
            }else if(value instanceof ActionContainer){
                Thing athing = ((ActionContainer) value).getThing();
                if(athing != null){
                    for(Thing acThing : athing.getChilds()){
                        items.add(createTreModelItem(parentItem, acThing.getMetadata().getName(), value.getClass().getName(), acThing));
                    }
                }
            }else if(value instanceof Map){
                Map<?,?> vMap = (Map<?,?>) value;
                int index = 0;
                items.add(createTreModelItem(parentItem, "size", value.getClass().getName(), vMap.size()));
                for(Object key : vMap.keySet()){
                    String name = String.valueOf(key);
                    items.add(createTreModelItem(parentItem, name, null, vMap.get(key)));
                    index++;

                    //避免显示过多出问题
                    if(index > 1000){
                        break;
                    }
                }
            }else if(value instanceof List || value.getClass().getName().startsWith("[")){
                List vlist;
                if(value instanceof List){
                    vlist = (List) value;
                }else{
                    vlist = new ArrayList<>();
                    Collections.addAll(vlist, (Object[]) value);
                }
                items.add(createTreModelItem(parentItem, "size", null, vlist.size()));

                int index = 0;
                for(Object v : vlist){
                    String name;
                    if(index < 10){
                        name = "000" + index;
                    }else if(index < 100){
                        name = "00" + index;
                    }else {
                        name = "0" + index;
                    }
                    index++;
                    items.add(createTreModelItem(parentItem, name, null, vlist.get(index)));

                    if(index >= 1000){
                        //最多显示1000个
                        break;
                    }
                }
            }
        }catch(Throwable t){
            t.printStackTrace();
        }

        return items;
    }
}
